//
//  ControlFlowGraph.h
//  ConstructGccfg2.0
//
//  Created by Bryce Holton on 12/4/12.
//  Copyright (c) 2012 Bryce Holton. All rights reserved.
//

#ifndef __ConstructGccfg2_0__ControlFlowGraph__
#define __ConstructGccfg2_0__ControlFlowGraph__

#include <iostream>
#include "common.h"
#include "BasicBlock.h"
#include <set>

class ControlFlowGraphLoop;

class ControlFlowGraph
{
public:
    ControlFlowGraph();
    virtual ~ControlFlowGraph();
    //This looks through all the basic blocks in a cfg and finds the one with the same id number.
    virtual BasicBlock *FindBlockInSet(int);
    //Finds a block in the cfg list and removes it
    void RemoveBlockFromSet(BasicBlock &);
    //Once a loop is found we remove the blocks that are in the loop set from this set.
    void RemoveBlocksNotInThisSet(set<BasicBlock *> &);
    //Adds blocks to the set that take the place of the loops.
    void FindLoopsInBlockSet(ControlFlowGraphLoop &);
    //Not sure.
    void CleanUpBlocks();
    virtual void DepthFirstSearch(BasicBlock &);
    
    void SetFunctionName(string);
    void SetRootBlock(BasicBlock &);
    void SetExitBlock(BasicBlock &);
    void SetBlockSet(set<BasicBlock *> &);
    
    string GetFunctionName();
    BasicBlock *GetRootBlock();
    BasicBlock *GetExitBlock();
    set<BasicBlock *> GetBlockSet();
    
    //This finds all the children of the cfg.
    set<BasicBlock *> GetSetOfChildrenThisGraph();
    
private:
    string functionName;
    BasicBlock *rootBlock, *exitBlock;
    set<BasicBlock *> blockSet;
};

class ControlFlowGraphLoop : public ControlFlowGraph
{
public:
    ControlFlowGraphLoop(int);
    virtual ~ControlFlowGraphLoop();
    int GetLoopId();
    BasicBlock *FindLoopExitBlock(set<BasicBlock *> &);
    //There may be children of some loop nodes that are not in this loop.
    //We remove those children here and point those edges to the loop exit.
    void SeverChildrenNotInThisLoop();
    
private:
    int loopId;
    set<BasicBlock *> GetExitChildren();
};

#endif /* defined(__ConstructGccfg2_0__ControlFlowGraph__) */
